﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Model.Elements
{
    public class HttpRequestPacket : HttpPacket
    {
        public List<HttpHeader> lstHeaders = new List<HttpHeader>();
        public string method = string.Empty;
        public string uri = string.Empty;
        public string version = string.Empty;
        public byte[] data = null;
        public bool ssl;

        public string clientIp = string.Empty;
        // A plugin can force a response for this request by asigning a responsepacket
        private HttpResponsePacket forcedResponsePacket = null;

        public bool dropped = false; // set it to drop the packet

        public HttpRequestPacket(string method, string uri, string version, string ip, bool ssl)
        {
            this.method = method;
            this.uri = uri;
            this.version = version;
            clientIp = ip;
            this.ssl = ssl;

            lstHeaders = new List<HttpHeader>();
        }

        public HttpRequestPacket(string method, string uri, string version, bool ssl) : this(method, uri, version, string.Empty, ssl)
        {
        }

        public void SetforcedResponsePacket(HttpResponsePacket packet)
        {
            forcedResponsePacket = packet;
            forcedResponsePacket.SetRequestPacket(this);
        }

        public HttpResponsePacket GetforcedResponsePacket()
        {
            return forcedResponsePacket;
        }


        public void SetData(byte[] data)
        {
            this.data = data;
        }

        public void AddHeader(HttpHeader header)
        {
            lstHeaders.Add(header);
        }

        /// <summary>
        /// Also, remove duplicates
        /// </summary>
        /// <param name="name"></param>
        /// <param name="caseSensitive"></param>
        /// <returns></returns>
        public bool RemoveHeader(string name, bool caseSensitive)
        {
            bool remove = false;
            bool removed = false;
            for (int i = lstHeaders.Count - 1; i >= 0; i--)
            {
                if (caseSensitive && lstHeaders[i].name == name)
                    remove = true;
                else if (!caseSensitive && lstHeaders[i].name.ToUpper() == name.ToUpper())
                    remove = true;

                if (remove)
                {
                    lstHeaders.Remove(lstHeaders[i]);
                    removed = true;
                    remove = false;
                }
            }

            return removed;
        }

        public bool RemoveHeader(HttpHeader header)
        {
            return lstHeaders.Remove(header);
        }

        public HttpHeader GetHeader(string headerName, bool caseSensitive)
        {
            for (int i = 0; i < lstHeaders.Count; i++)
            {
                if (caseSensitive && lstHeaders[i].name == headerName)
                    return lstHeaders[i];
                else if (!caseSensitive && lstHeaders[i].name.ToUpper() == headerName.ToUpper())
                    return lstHeaders[i];
            }

            return null;
        }

        public bool ExistHeader(string name, bool caseSensitive)
        {
            for (int i = 0; i < lstHeaders.Count; i++)
            {
                if (caseSensitive && lstHeaders[i].name == name)
                    return true;
                else if (!caseSensitive && lstHeaders[i].name.ToUpper() == name.ToUpper())
                    return true;
            }

            return false;
        }

        public int NumberOfHeaderOcurrences(string headerName, bool caseSensitive)
        {
            int ocurrences = 0;

            for (int i = 0; i < lstHeaders.Count; i++)
            {

                if (caseSensitive && lstHeaders[i].name == headerName)
                    ocurrences++;
                else if (!caseSensitive && lstHeaders[i].name.ToUpper() == headerName.ToUpper())
                    ocurrences++;
            }

            return ocurrences;
        }


        public override string ToString()
        {
            StringBuilder output = new StringBuilder();

            output.Append(string.Format("{0} {1} {2}\r\n", method, uri, version));
            /*
            for (int h = 0; h < lstHeaders.Count; h++)
            {
                output.Append(string.Format("{0}: {1}\r\n", lstHeaders[h].name, lstHeaders[h].value));
            }
            output.Append("\r\n");
            if (data != null)
                output.Append(ASCIIEncoding.ASCII.GetString(data));
            */
            return output.ToString();
            }

    }
}
